package com.ruoyi.server.service.impl;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageInfo;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.PageUtils;
import com.ruoyi.order.domain.OrderInfo;
import com.ruoyi.order.domain.dto.OrderInfoSnapshotDTO;
import com.ruoyi.order.enums.OrderStatusEnum;
import com.ruoyi.order.service.IOrderInfoService;
import com.ruoyi.server.domain.dto.ServerTaskAddDTO;
import com.ruoyi.server.domain.dto.ServerTaskPageDTO;
import com.ruoyi.server.domain.dto.ServerTaskChangeStateDTO;
import com.ruoyi.server.domain.dto.ServerTaskUpdateDTO;
import com.ruoyi.server.domain.vo.ServerTaskAppVO;
import com.ruoyi.server.domain.vo.ServerTaskPeopleCountVO;
import com.ruoyi.server.domain.vo.ServerTaskUserAccountVO;
import com.ruoyi.server.domain.vo.ServerTaskVO;
import com.ruoyi.server.enums.TaskStateEnum;
import com.ruoyi.user.domain.dto.AppUserAccountSnapshootDTO;
import com.ruoyi.user.domain.vo.AppUserAccountSnapshootVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.server.mapper.ServerTaskMapper;
import com.ruoyi.server.domain.ServerTask;
import com.ruoyi.server.service.IServerTaskService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 区服任务Service业务层处理
 *
 * @author ghostmen
 * @date 2024-10-31
 */
@Service
public class ServerTaskServiceImpl extends ServiceImpl<ServerTaskMapper, ServerTask> implements IServerTaskService {

    @Autowired
    private ServerTaskMapper serverTaskMapper;
    @Autowired
    private IOrderInfoService orderInfoService;

    /**
     * 查询区服任务
     *
     * @param taskId 区服任务主键
     * @return 区服任务
     */
    @Override
    public ServerTaskVO selectServerTaskByTaskId(Long taskId) {
        ServerTask serverTask = serverTaskMapper.selectServerTaskByTaskId(taskId);
        if (Objects.isNull(serverTask)) {
            return null;
        }
        ServerTaskVO serverTaskVO = BeanUtil.copyProperties(serverTask, ServerTaskVO.class);
        serverTaskVO.setStateName(TaskStateEnum.getByCode(serverTaskVO.getState()).getDescribe());
        ServerTaskPeopleCountVO peopleCountVO = orderInfoService.getApplyPeopleCountByTaskId(serverTaskVO.getTaskId());
        serverTaskVO.setApplyPeopleCount(Objects.isNull(peopleCountVO) ? 0 : peopleCountVO.getPeopleCount());
        List<OrderInfo> orderInfoList = orderInfoService.selectOrderInfoListByTaskId(serverTaskVO.getTaskId());
        if (CollectionUtils.isNotEmpty(orderInfoList)) {
            List<AppUserAccountSnapshootVO> accountSnapshootDTOS = orderInfoList.stream().map(orderInfo -> {
                OrderInfoSnapshotDTO orderInfoSnapshotDTO = JSON.parseObject(orderInfo.getOrderSnapshot(), OrderInfoSnapshotDTO.class);
                AppUserAccountSnapshootVO appUserAccountSnapshootVO = BeanUtil.copyProperties(orderInfoSnapshotDTO.getAccountSnapshoot(), AppUserAccountSnapshootVO.class);
                appUserAccountSnapshootVO.setRemark(orderInfo.getRemark());
                return appUserAccountSnapshootVO;
            }).collect(Collectors.toList());
            serverTaskVO.setAppUserAccountList(accountSnapshootDTOS);
        }
        return serverTaskVO;
    }

    /**
     * 查询区服任务
     *
     * @param taskIds 区服任务主键
     * @return 区服任务
     */
    @Override
    public List<ServerTask> selectServerTaskByTaskIds(List<Long> taskIds) {
        return serverTaskMapper.selectServerTaskByTaskIds(taskIds);
    }

    /**
     * 查询区服任务列表
     *
     * @param serverTask 区服任务
     * @return 区服任务
     */
    @Override
    public PageInfo<ServerTaskVO> selectServerTaskList(ServerTask serverTask) {
        PageUtils.startPage();
        List<ServerTask> serverTaskList = serverTaskMapper.selectServerTaskList(serverTask);
        if (CollectionUtils.isEmpty(serverTaskList)) {
            return new PageInfo<>();
        }
        PageInfo<ServerTask> taskPageInfo = new PageInfo<>(serverTaskList);
        PageInfo<ServerTaskVO> pageInfo = PageUtils.copyPage(taskPageInfo, ServerTaskVO.class);
        if (CollectionUtils.isNotEmpty(taskPageInfo.getList())) {
            List<ServerTaskVO> serverTaskVOList = pageInfo.getList();
            List<Long> taskIds = serverTaskVOList.stream().map(ServerTaskVO::getTaskId).collect(Collectors.toList());
            List<ServerTaskPeopleCountVO> peopleCountVOList = orderInfoService.getApplyPeopleCountByTaskIds(taskIds);
            Map<Long, Integer> peopleCountMap = peopleCountVOList.stream().collect(Collectors.toMap(ServerTaskPeopleCountVO::getTaskId, ServerTaskPeopleCountVO::getPeopleCount));
            serverTaskVOList.forEach(serverTaskVO -> {
                if (!Objects.isNull(peopleCountMap)) {
                    Integer peopleCount = peopleCountMap.get(serverTaskVO.getTaskId());
                    serverTaskVO.setApplyPeopleCount(peopleCount == null ? 0 : peopleCount);
                } else {
                    serverTaskVO.setApplyPeopleCount(0);
                }
                serverTaskVO.setStateName(TaskStateEnum.getByCode(serverTaskVO.getState()).getDescribe());
            });
            return pageInfo;
        }
        return new PageInfo<>();
    }

    /**
     * 新增区服任务
     *
     * @param addDTO 区服任务
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertServerTask(ServerTaskAddDTO addDTO) {
        ServerTask serverTask = BeanUtil.copyProperties(addDTO, ServerTask.class);
        //默认草稿
        serverTask.setTaskId(IdWorker.getId());
        serverTask.setState(TaskStateEnum.DRAFT.getCode());
        serverTask.setCreateBy(addDTO.getLoginUser().getUsername());
        serverTask.setCreateTime(DateUtils.getNowDate());

        if (null != addDTO.getDiscountPrice() && BigDecimal.ZERO.compareTo(addDTO.getDiscountPrice()) > 0) {
            throw new ServiceException("优惠价不能小于0");
        }

        return serverTaskMapper.insertServerTask(serverTask);
    }


    /**
     * 修改区服任务
     *
     * @param updateDTO 区服任务
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateServerTask(ServerTaskUpdateDTO updateDTO) {
        ServerTask task = serverTaskMapper.selectServerTaskByTaskId(updateDTO.getTaskId());
        if (Objects.isNull(task)) {
            throw new ServiceException("区服任务不存在");
        }
        if (!TaskStateEnum.DRAFT.getCode().equals(task.getState())) {
            throw new ServiceException("非草稿状态禁止修改");
        }
        ServerTask serverTask = BeanUtil.copyProperties(updateDTO, ServerTask.class);
        serverTask.setUpdateBy(updateDTO.getLoginUser().getUsername());
        serverTask.setUpdateTime(DateUtils.getNowDate());

        if (null != updateDTO.getDiscountPrice() && BigDecimal.ZERO.compareTo(updateDTO.getDiscountPrice()) > 0) {
            throw new ServiceException("优惠价不能小于0");
        }
        return serverTaskMapper.updateServerTask(serverTask);
    }

    /**
     * 批量删除区服任务
     *
     * @param taskIds 需要删除的区服任务主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteServerTaskByTaskIds(Long[] taskIds) {
        List<ServerTask> serverTasks = serverTaskMapper.selectServerTaskByTaskIds(Arrays.asList(taskIds));
        List<ServerTask> taskList = serverTasks.stream().filter(serverTask -> TaskStateEnum.DRAFT.getCode().equals(serverTask.getState())).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(taskList) || taskList.size() != taskIds.length) {
            throw new ServiceException("非草稿状态的区服任务禁止删除");
        }
        return serverTaskMapper.deleteServerTaskByTaskIds(taskIds);
    }

    /**
     * 删除区服任务信息
     *
     * @param taskId 区服任务主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteServerTaskByTaskId(Long taskId) {
        return serverTaskMapper.deleteServerTaskByTaskId(taskId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int changeState(ServerTaskChangeStateDTO changeStateDTO) {
        ServerTask serverTask = serverTaskMapper.selectServerTaskByTaskId(changeStateDTO.getTaskId());
        if (Objects.isNull(serverTask)) {
            throw new ServiceException("区服任务不存在");
        }
        switch (TaskStateEnum.getByCode(changeStateDTO.getState())) {
            //发布
            case RELEASE:
                if (!TaskStateEnum.DRAFT.getCode().equals(serverTask.getState())) {
                    throw new ServiceException("仅草稿状态下可以发布");
                }
                break;
            //完成
            case COMPLETE:
                if (!TaskStateEnum.BEGIN.getCode().equals(serverTask.getState())) {
                    throw new ServiceException("仅开始状态下可以完成");
                }
                break;
            //开始任务
            case BEGIN:
                if (!TaskStateEnum.RELEASE.getCode().equals(serverTask.getState())) {
                    throw new ServiceException("仅发布状态下可以开始");
                }
                break;
            default:
                throw new ServiceException("区服任务状态异常");
        }

        int i = serverTaskMapper.update(null, new UpdateWrapper<ServerTask>()
                .lambda()
                .set(ServerTask::getUpdateBy, changeStateDTO.getLoginUser().getUsername())
                .set(ServerTask::getUpdateTime, DateUtils.getNowDate())
                .set(ServerTask::getState, changeStateDTO.getState())
                .eq(ServerTask::getTaskId, changeStateDTO.getTaskId())
        );

        switch (TaskStateEnum.getByCode(changeStateDTO.getState())) {
            case BEGIN:
                //区服任务开始后同步订单为进行中
                orderInfoService.updateOrderByTaskId(changeStateDTO.getTaskId(), OrderStatusEnum.UNDER_WAY);
                break;
            case COMPLETE:
                //区服任务完成后同步订单为已完成
                orderInfoService.updateOrderByTaskId(changeStateDTO.getTaskId(), OrderStatusEnum.FINISH);
                break;
        }

        return i;
    }

    @Override
    public PageInfo<ServerTaskAppVO> taskListByRegionId(ServerTaskPageDTO pageDTO) {
        List<ServerTask> serverTaskList = serverTaskMapper.taskListByRegionId(pageDTO);
        if (CollectionUtils.isEmpty(serverTaskList)) {
            return new PageInfo<>();
        }
        PageInfo<ServerTask> pageInfo = new PageInfo<>(serverTaskList);
        PageInfo<ServerTaskAppVO> voPageInfo = PageUtils.copyPage(pageInfo, ServerTaskAppVO.class);

        List<ServerTaskAppVO> serverTaskVOList = voPageInfo.getList();

        List<Long> taskIds = serverTaskVOList.stream().map(ServerTaskAppVO::getTaskId).collect(Collectors.toList());
        // 获取任务报名人数
        List<ServerTaskPeopleCountVO> peopleCountVOList = orderInfoService.getApplyPeopleCountByTaskIds(taskIds);
        // 获取当前用户订单信息
//        List<OrderInfo> orderInfoList = orderInfoService.getOrderInfoListByTaskIdsAndUserId(taskIds, pageDTO.getUserId());
//        List<Long> existTaskIds;
//        if (CollectionUtils.isNotEmpty(orderInfoList)) {
//            existTaskIds = orderInfoList.stream().map(OrderInfo::getTaskId).collect(Collectors.toList());
//        } else {
//            existTaskIds = null;
//        }

        Map<Long, Integer> peopleCountMap = peopleCountVOList.stream().collect(Collectors.toMap(ServerTaskPeopleCountVO::getTaskId, ServerTaskPeopleCountVO::getPeopleCount));
        serverTaskVOList.forEach(serverTaskVO -> {
            if (!Objects.isNull(peopleCountMap)) {
                Integer peopleCount = peopleCountMap.get(serverTaskVO.getTaskId());
                serverTaskVO.setApplyPeopleCount(peopleCount == null ? 0 : peopleCount);
//                if (CollectionUtils.isNotEmpty(existTaskIds)) {
//                    serverTaskVO.setApplyFlag(existTaskIds.contains(serverTaskVO.getTaskId()) ? Boolean.TRUE : Boolean.FALSE);
//                }
            } else {
                serverTaskVO.setApplyPeopleCount(0);
            }
            serverTaskVO.setStateName(TaskStateEnum.getByCode(serverTaskVO.getState()).getDescribe());
        });
        return voPageInfo;
    }

    @Override
    public ServerTask getAppServerTaskByTaskId(Long taskId) {
        ServerTask serverTask = serverTaskMapper.getAppServerTaskByTaskId(taskId);
        return serverTask;
    }

    @Override
    public List<ServerTask> getServerTaskList() {
        return serverTaskMapper.getServerTaskList();
    }

    @Override
    public List<ServerTaskUserAccountVO> selectServerTaskAppUserAccountListBy(Long taskId) {
        ServerTask serverTask = serverTaskMapper.selectServerTaskByTaskId(taskId);
        if (Objects.isNull(serverTask)) {
            throw new ServiceException("区服任务不存在");
        }
        List<OrderInfo> orderInfoList = orderInfoService.selectOrderInfoListByTaskId(serverTask.getTaskId());
        if (CollectionUtils.isNotEmpty(orderInfoList)) {
            List<ServerTaskUserAccountVO> accountSnapshootDTOS = orderInfoList.stream().map(orderInfo -> {
                OrderInfoSnapshotDTO orderInfoSnapshotDTO = JSON.parseObject(orderInfo.getOrderSnapshot(), OrderInfoSnapshotDTO.class);
                ServerTaskUserAccountVO serverTaskUserAccountVO = BeanUtil.copyProperties(orderInfoSnapshotDTO.getAccountSnapshoot(), ServerTaskUserAccountVO.class);
                serverTaskUserAccountVO.setTaskName(serverTask.getTaskName());
                serverTaskUserAccountVO.setRegionName(serverTask.getRegionName());
                serverTaskUserAccountVO.setRemark(orderInfo.getRemark());
                return serverTaskUserAccountVO;
            }).collect(Collectors.toList());
            return accountSnapshootDTOS;
        }
        return null;
    }

}
